using System.Collections;
using System.Collections.Generic;

namespace ColladaDotNet.SimpleMesh
{
	public class VertexBuffer : IEnumerable<Vertex>
	{

		List<Vertex> verticesList = new List<Vertex>();
		private Dictionary<Vertex, int> uniqueVertices = new Dictionary<Vertex, int>();

		public int Count
		{
			get
			{
				return uniqueVertices.Count;
			}
		}

		public int Add(Vertex v)
		{
			int res;
			if (uniqueVertices.TryGetValue(v,out res))
			{
				return res;
			}
			var index = verticesList.Count;
			uniqueVertices.Add(v, index);
			verticesList.Add(v);
			return index;
		}

		public double[] PositionXYZArray()
		{
			double[] res = new double[verticesList.Count*3];
			for (int i = 0; i < verticesList.Count; i++)
			{
				var vertex = verticesList[i];
				var index0 = i*3;
				res[index0] = vertex.Position.X;
				res[index0+1] = vertex.Position.Y;
				res[index0+2] = vertex.Position.Z;
			}
			return res;
		}

		public double[] NormalXYZArray()
		{
			double[] res = new double[verticesList.Count * 3];
			for (int i = 0; i < verticesList.Count; i++)
			{
				var vertex = verticesList[i];
				var index0 = i * 3;
				res[index0] = vertex.Normal.X;
				res[index0 + 1] = vertex.Normal.Y;
				res[index0 + 2] = vertex.Normal.Z;
			}
			return res;
		}

		public double[] ColorRGBArray()
		{
			double[] res = new double[verticesList.Count * 3];
			for (int i = 0; i < verticesList.Count; i++)
			{
				var vertex = verticesList[i];
				var index0 = i * 3;
				res[index0] = vertex.Color.X;
				res[index0 + 1] = vertex.Color.Y;
				res[index0 + 2] = vertex.Color.Z;
			}
			return res;
		}

		public double[] TexCoord0XYZArray()
		{
			double[] res = new double[verticesList.Count * 3];
			for (int i = 0; i < verticesList.Count; i++)
			{
				var vertex = verticesList[i];
				var index0 = i * 3;
				var coord = vertex.TexCoord0.TexCoord;
				res[index0] = coord.X;
				res[index0 + 1] = coord.Y;
				res[index0 + 2] = coord.Z;
			}
			return res;
		}

		public Vertex this[int i]
		{
			get
			{
				return verticesList[i];
			}
		}

		/// <summary>
		/// Returns an enumerator that iterates through the collection.
		/// </summary>
		/// <returns>
		/// A <see cref="T:System.Collections.Generic.IEnumerator`1"></see> that can be used to iterate through the collection.
		/// </returns>
		/// <filterpriority>1</filterpriority>
		public IEnumerator<Vertex> GetEnumerator()
		{
			return verticesList.GetEnumerator();
		}

		/// <summary>
		/// Returns an enumerator that iterates through a collection.
		/// </summary>
		/// <returns>
		/// An <see cref="T:System.Collections.IEnumerator"></see> object that can be used to iterate through the collection.
		/// </returns>
		/// <filterpriority>2</filterpriority>
		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}

		public void Scale(double factor)
		{
			for (int i = 0; i < verticesList.Count; i++)
			{
				verticesList[i].Scale(factor);
			}
		}
	}
}